﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using MySql.Data.MySqlClient;
using DateBaseConnectionPool;

namespace TestMySqlConnetPoll
{
    public class ObjGybdcType
    {
        public objSingleAnalogStruct objset = new objSingleAnalogStruct();
        public short dotnum1= 0;
        public int start1 = 0;
        public List<ObjRCurValue> qx1 = new List<ObjRCurValue>();
        public short dotnum2 = 0;
        public int start2 = 0;
        public List<ObjRCurValue> qx2 = new List<ObjRCurValue>();
        public short dotnum3;
        public int start3 = 0;
        public List<ObjRCurValue> qx3 = new List<ObjRCurValue>();
    }

    public class GybdcQxTable
    {
        #region 外部函数接口，高压不对称曲线    变量定义
        
        public List<DateTime> TimeList = new List<DateTime>();    //高压不对称时间表
        public string  GybdcDevNo = "";       //高压不对称值对应的设备号
        public Dictionary<DateTime, ObjGybdcType> ValueList = new Dictionary<DateTime, ObjGybdcType>(); //时间做键值

        public bool Ready_TimeList = false;
        public bool Ready_ValueList = false;
        public int ErrorFlag = 0;


        public struct ThreadStruct
        {
            public string TableName;
            public int codeType;
            public Int16 dev_no;
            public int u_time;
        }

        public void ReadTimeList(string DevName)
        {
            ErrorFlag = 0;
            TimeList.Clear();
            Ready_TimeList = false;
            ThreadStruct obj = new ThreadStruct();
            obj.TableName = "gybdcqx";
            obj.codeType = 0x13;
            obj.dev_no = (short)c_Device.GetGybdcDyDevNo(DevName);
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadTimeList), obj);
        }

        public void ReadValueList(string DevName, DateTime d_time)
        {
            ErrorFlag = 0;
            Ready_ValueList = false;
            if (GybdcDevNo == DevName)
            {
                if (ValueList.Keys.Contains(d_time))
                {
                    Ready_ValueList = true;
                    return;
                }
            }
            else
            {
                GybdcDevNo = DevName;
                ValueList.Clear();
            }
            ThreadStruct obj = new ThreadStruct();
            obj.TableName = "gybdcqx";
            obj.codeType = 0x13;
            obj.dev_no = (short)c_Device.GetGybdcDyDevNo(DevName);
            obj.u_time = (int)MySql.DateTimeToTime_t(d_time);
            ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadReadValueList), obj);
        }

        #endregion

        #region  高压不对称曲线操作
        private Mutex keyMutex = new Mutex();
        static private int keykey = 0;
        /// <summary>
        /// 加入到高压不对称时间列表，只保存单个设备的时间列表
        /// </summary>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        private void AddToTimeList(int u_time)
        {
            DateTime t = MySql.Time_tToDateTime(u_time);
            if (TimeList.Contains(t)) { }
            else
            {                
                TimeList.Add(t);
            }
        }

        /// <summary>
        /// 读取高压不对称曲线时间列表，依据设备号
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="dev_no"></param>
        /// <returns></returns>
        private void ThreadReadTimeList(object o)
        {
            ThreadStruct obj = (ThreadStruct)o;
            string TableName = obj.TableName;
            int codetype = obj.codeType;
            Int16 dev_no = obj.dev_no;

            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    ErrorFlag = 1;
                }
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append(string.Format("select u_time from {0} where dev_no = {1} and codetype = {2}", TableName, dev_no, (byte)codetype));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {
                            int u_time = read.GetInt32(0);
                            AddToTimeList(u_time);
                        }
                        read.Close();
                        Ready_TimeList = true;
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 3;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 4;
                    }
                }
                else ErrorFlag = 6;
            }
            else ErrorFlag = 7;
        }

        /// <summary>
        /// 把取出的高压不对称曲线加入到缓冲区中
        /// </summary>
        /// <param name="dev_no"></param>
        /// <param name="u_time"></param>
        /// <param name="dot1"></param>
        /// <param name="qx1"></param>
        /// <param name="dot2"></param>
        /// <param name="qx2"></param>
        /// <param name="dot3"></param>
        /// <param name="qx3"></param>
        private void AddToGybdcDevValueList(int codetype, Int16 dev_no, int u_time, short dot1, int st1,byte[] qx1, short dot2, int st2,byte[] qx2, short dot3, int st3,byte[] qx3)
        {
            ObjGybdcType tmp = new ObjGybdcType();
            tmp.objset = c_Device.GetGybdcqx_AnalogConfigSet(dev_no);
            tmp.dotnum1 = dot1;
            tmp.dotnum2 = dot2;
            tmp.dotnum3 = dot3;
            tmp.start1 = st1;
            tmp.start2 = st2;
            tmp.start3 = st3;

            ObjRCurValue tmpValue = new ObjRCurValue();
            string AnalogName = "高压不对称波形";
            int m = 0;
            for(int i =0;i<dot1;i++)
            {                
                int value = qx1[m] + (qx1[m + 1] << 8);
                m += 2;
                tmpValue.tValue = c_RealTimeValue.ConvertAnalogValue(AnalogName,(short)value);
                tmpValue.wValue = (short)value;
                tmp.qx1.Add(tmpValue);
            }
            m = 0;
            for (int i = 0; i < dot2; i++)
            {
                int value = qx2[m] + (qx2[m + 1] << 8);
                m += 2;
                tmpValue.tValue = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)value);
                tmpValue.wValue = (short)value;
                tmp.qx2.Add(tmpValue);
            }
            m = 0;
            for (int i = 0; i < dot3; i++)
            {
                int value = qx3[m] + (qx3[m + 1] << 8);
                m += 2;
                tmpValue.tValue = c_RealTimeValue.ConvertAnalogValue(AnalogName, (short)value);
                tmpValue.wValue = (short)value;
                tmp.qx3.Add(tmpValue);
            }
            DateTime d_time = MySql.Time_tToDateTime(u_time);
            ValueList.Add(d_time, tmp);
        }
        /// <summary>
        /// 从数据库中读取高压不对称数据
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="dev_no"></param>
        /// <param name="u_time"></param>
        /// <returns></returns>
        private void ThreadReadValueList(object o)
        {
            ThreadStruct obj = (ThreadStruct)o;
            string TableName = obj.TableName;
            int codetype = obj.codeType;
            Int16 dev_no = obj.dev_no;
            int u_time = obj.u_time;

            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    ErrorFlag = 1;
                }
                if (con != null)
                {
                    StringBuilder SelectStatement = new StringBuilder();

                    SelectStatement.Append(string.Format("select dotNum1,start1,qx1,dotNum2,start2,qx2,dotNum3,start3,qx3 from {0} where dev_no = {1} and u_time = {2} and codetype = {3}", TableName, dev_no, u_time, (byte)codetype));

                    try
                    {
                        MySqlCommand selectCommand = new MySqlCommand(SelectStatement.ToString(), con);
                        selectCommand.CommandTimeout = 120;   //120s操作超时

                        MySqlDataReader read = selectCommand.ExecuteReader();
                        while (read.Read())
                        {                            
                            short dot1 = read.GetInt16(read.GetOrdinal("dotNum1"));
                            int st1 = read.GetInt32(read.GetOrdinal("start1"));
                            byte[] qx1 = new byte[4000];
                            read.GetBytes(read.GetOrdinal("qx1"), 0, qx1, 0, dot1*2);
                            
                            short dot2 = read.GetInt16(read.GetOrdinal("dotNum2"));
                            int st2 = read.GetInt32(read.GetOrdinal("start2"));
                            byte[] qx2 = new byte[4000];
                            read.GetBytes(read.GetOrdinal("qx2"), 0, qx2, 0, dot2*2);

                            short dot3 = read.GetInt16(read.GetOrdinal("dotNum3"));
                            int st3 = read.GetInt32(read.GetOrdinal("start3"));
                            byte[] qx3 = new byte[4000];
                            read.GetBytes(read.GetOrdinal("qx3"), 0, qx3, 0, dot3*2);
                            AddToGybdcDevValueList(codetype, dev_no, u_time, dot1,st1, qx1, dot2, st2,qx2, dot3, st3,qx3);
                        }
                        read.Close();
                        Ready_ValueList = true;
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 3;
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        ErrorFlag = 4;
                    }
                }
                else ErrorFlag = 6;
            }
            else ErrorFlag = 7;
        }

        /// <summary>
        /// 插入高压不对称表
        /// </summary>
        /// <param name="TableName"></param>
        /// <param name="u_time"></param>
        /// <param name="dev_no"></param>
        /// <param name="dotNum1"></param>
        /// <param name="qx1"></param>
        /// <param name="dotNum2"></param>
        /// <param name="qx2"></param>
        /// <param name="dotNum3"></param>
        /// <param name="qx3"></param>
        /// <returns></returns>
        public bool InsertGYBDCqxTable(int u_time, int codetype, Int16 dev_no, Int16 dotNum1,int start1, byte[] qx1, Int16 dotNum2,int start2, byte[] qx2, Int16 dotNum3,int start3, byte[] qx3)
        {
            bool tmpFlag = false;
            string TableName = "gybdcqx";
            if (TableName == "") return tmpFlag;
            if (MySql.c != null && MySql.c.State == PoolState.Run)
            {
                MySqlConnection con = new MySqlConnection();
                string key = TableName + DateTime.Now.Second.ToString() + DateTime.Now.Millisecond.ToString() + Interlocked.Increment(ref keykey).ToString();
                try
                {
                    con = (MySqlConnection)MySql.c.GetConnectionFormPool(key);
                }
                catch (MySqlException ex)
                {
                    //写异常日志
                    tmpFlag = false;
                }
                
                if (con != null)
                {
                    StringBuilder InsertStatement = new StringBuilder();

                    InsertStatement.Append(string.Format("insert into {0}(u_time,codetype,dev_no,dotNum1,start1,qx1,dotNum2,start2,qx2,dotNum3,start3,qx3)", TableName));

                    InsertStatement.Append("values(?u_time,?codetype,?dev_no,?dotNum1,?start1,?qx1,?dotNum2,?start2,?qx2,?dotNum3,?start3,?qx3)");

                    MySqlCommand InsertCommand = new MySqlCommand(InsertStatement.ToString(), con);

                    InsertCommand.Parameters.Add(new MySqlParameter("?u_time", MySqlDbType.UInt32)).Value = u_time;
                    InsertCommand.Parameters.Add(new MySqlParameter("?codetype", MySqlDbType.Byte)).Value = codetype;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dev_no", MySqlDbType.UInt16)).Value = dev_no;
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNum1", MySqlDbType.UInt16)).Value = dotNum1;
                    InsertCommand.Parameters.Add(new MySqlParameter("?start1", MySqlDbType.UInt16)).Value = start1;
                    InsertCommand.Parameters.Add(new MySqlParameter("?qx1", MySqlDbType.VarBinary)).Value = qx1.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNum2", MySqlDbType.UInt16)).Value = dotNum2;
                    InsertCommand.Parameters.Add(new MySqlParameter("?start2", MySqlDbType.UInt16)).Value = start2;
                    InsertCommand.Parameters.Add(new MySqlParameter("?qx2", MySqlDbType.VarBinary)).Value = qx2.ToArray();
                    InsertCommand.Parameters.Add(new MySqlParameter("?dotNum3", MySqlDbType.UInt16)).Value = dotNum3;
                    InsertCommand.Parameters.Add(new MySqlParameter("?start3", MySqlDbType.UInt16)).Value = start3;
                    InsertCommand.Parameters.Add(new MySqlParameter("?qx3", MySqlDbType.VarBinary)).Value = qx3.ToArray();

                    try
                    {
                        int k = InsertCommand.ExecuteNonQuery();
                        if (k == 1) tmpFlag = true;        //写入成功
                        else tmpFlag = false;              //写入失败
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                        tmpFlag = false;       //写入失败
                    }
                    try
                    {
                        MySql.c.DisposeConnection(key);
                    }
                    catch (MySqlException e)
                    {
                        //写异常日记
                    }
                }
            }
            return tmpFlag;
        }
        #endregion
    }
}
